package dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.TypedQuery;

import util.Conversion;
import dto.RoomDTO;
import entities.Interview;
import entities.Room;

/**
 * Session Bean implementation class RoomDAO
 */
@Stateless
public class RoomDAO implements RoomDAORemote {

	/**
	 * Default constructor.
	 */
	@PersistenceContext
	EntityManager em;

	@Override
	public void addRoom(RoomDTO room) {
		Conversion conv = new Conversion();
		Room r = null;
		try {
			r = conv.fromRoomDTOToRoom(room);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (em.find(Room.class, r.getId()) != null) {
			em.merge(r);
		} else
			em.persist(r);
	}

	@Override
	public void deleteRoom(RoomDTO room) {
		Query q = em.createQuery("DELETE FROM Room r WHERE r.id= :id");
		q.setParameter("id", room.getId());
		q.executeUpdate();
	}

	@Override
	public List<RoomDTO> getAllRooms() {
		List<RoomDTO> lista = new ArrayList<RoomDTO>();
		TypedQuery<Room> query = em.createQuery("SELECT r FROM Room r",
				Room.class);
		List<Room> result = query.getResultList();
		for (Room r : result) {
			RoomDTO rooms = new RoomDTO();
			rooms.setId(r.getId());
			rooms.setAddress(r.getAddress());
			rooms.setNumberOfStations(r.getNumberOfStations());
			lista.add(rooms);
		}
		return lista;
	}

	@Override
	public void updateRoom(RoomDTO oldRoom, RoomDTO newRoom) {
		String query = "UPDATE Rooms SET numberOfStations = ? WHERE id = ?";
		em.createNativeQuery(query).setParameter(1,
				newRoom.getNumberOfStations()).setParameter(2, oldRoom.getId())
				.executeUpdate();
		Room r = em.find(Room.class, oldRoom.getId());
		if (r != null)
			r.setNumberOfStations(newRoom.getNumberOfStations());
	}

	@Override
	public RoomDTO getRoomById(int id) {
		Conversion conv = new Conversion();
		TypedQuery<Room> query = em.createQuery(
				"SELECT r FROM Room r WHERE r.id = :id", Room.class);
		query.setParameter("id", id);
		List<Room> room = query.getResultList();
		RoomDTO result = null;
		if (room != null && room.size() > 0) {
			try {
				result = conv.fromRoomToRoomDTO(room.get(0));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public RoomDTO getRoomByAddress(String address) {
		Conversion conv = new Conversion();
		TypedQuery<Room> query = em.createQuery(
				"SELECT r FROM Room r WHERE r.address = :address", Room.class);
		query.setParameter("address", address);
		List<Room> room = query.getResultList();

		RoomDTO result = null;
		if (room != null && room.size() > 0) {
			try {
				result = conv.fromRoomToRoomDTO(room.get(0));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	public int getFreePlaces(Calendar date, int idRoom) {
		System.out.println(date.get(Calendar.DATE) + "e data");

		TypedQuery<Interview> query = em.createQuery(
				"SELECT i FROM Interview i", Interview.class);
		List<Interview> interviews = query.getResultList();
		int size = 0;
		for (Interview i : interviews) {
			Calendar aux = Calendar.getInstance();
			aux.setTime(i.getDate());
			if (i.getRoom().getId() == idRoom)
				if (date.get(Calendar.DATE) == aux.get(Calendar.DATE)
						&& date.get(Calendar.MONTH) == aux.get(Calendar.MONTH)
						&& date.get(Calendar.YEAR) == aux.get(Calendar.YEAR))
					size++;
		}

		return size;

	}

	@SuppressWarnings("deprecation")
	public int getBusyPlacesInterval(Calendar hour, int idRoom, Calendar date) {
		TypedQuery<Interview> query = em.createQuery(
				"SELECT i FROM Interview i", Interview.class);
		List<Interview> interviews = query.getResultList();
		TypedQuery<Date> query1 = em.createQuery(
				"SELECT i.date FROM Interview i", Date.class);
		List<Date> dates = query1.getResultList();
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		int size = 0;
		for (Interview i : interviews) {
			if (i.getRoom() != null) {
				if (i.getRoom().getId() == idRoom) {
					Calendar aux = Calendar.getInstance();
					aux.setTime(dates.get(interviews.indexOf(i)));
					if (date.get(Calendar.DATE) == aux.get(Calendar.DATE)
							&& date.get(Calendar.MONTH) == aux
									.get(Calendar.MONTH)
							&& date.get(Calendar.YEAR) == aux
									.get(Calendar.YEAR)) {

						start.set(Calendar.HOUR_OF_DAY, i.getStartTime()
								.getHours());
						start.set(Calendar.MINUTE, i.getStartTime()
								.getMinutes());
						end
								.set(Calendar.HOUR_OF_DAY, i.getEndTime()
										.getHours());
						end.set(Calendar.MINUTE, i.getEndTime().getMinutes());
						if (start.get(Calendar.HOUR_OF_DAY) <= hour
								.get(Calendar.HOUR_OF_DAY)) {
							if ((hour.get(Calendar.HOUR_OF_DAY) < end
									.get(Calendar.HOUR_OF_DAY))
									|| (hour.get(Calendar.HOUR_OF_DAY) == end
											.get(Calendar.HOUR_OF_DAY) && end
											.get(Calendar.MINUTE) > 0)) {
								if (date.get(Calendar.HOUR_OF_DAY) <= end
										.get(Calendar.HOUR_OF_DAY)) {
									size++;
								}
							}
						}
					}
				}
			}
		}
		return size;
	}

	@SuppressWarnings("deprecation")
	public int getBusyPlacesInterval2(Calendar hour, int idRoom, Calendar date) {
		TypedQuery<Interview> query = em.createQuery(
				"SELECT i FROM Interview i", Interview.class);
		List<Interview> interviews = query.getResultList();
		TypedQuery<Date> query1 = em.createQuery(
				"SELECT i.date FROM Interview i", Date.class);
		List<Date> dates = query1.getResultList();
		Calendar start = Calendar.getInstance();
		Calendar end = Calendar.getInstance();
		int size = 0;
		for (Interview i : interviews) {
			if (i.getRoom() != null) {
				if (i.getRoom().getId() == idRoom) {
					Calendar aux = Calendar.getInstance();
					aux.setTime(dates.get(interviews.indexOf(i)));
					if (date.get(Calendar.DATE) == aux.get(Calendar.DATE)
							&& date.get(Calendar.MONTH) == aux
									.get(Calendar.MONTH)
							&& date.get(Calendar.YEAR) == aux
									.get(Calendar.YEAR)) {

						start.set(Calendar.HOUR_OF_DAY, i.getStartTime()
								.getHours());
						start.set(Calendar.MINUTE, i.getStartTime()
								.getMinutes());
						end
								.set(Calendar.HOUR_OF_DAY, i.getEndTime()
										.getHours());
						end.set(Calendar.MINUTE, i.getEndTime().getMinutes());
						if (start.get(Calendar.HOUR_OF_DAY) <= hour
								.get(Calendar.HOUR_OF_DAY)) {
							if ((hour.get(Calendar.HOUR_OF_DAY) < end
									.get(Calendar.HOUR_OF_DAY))
									|| (hour.get(Calendar.HOUR_OF_DAY) == end
											.get(Calendar.HOUR_OF_DAY) && end
											.get(Calendar.MINUTE) > 0)) {
								if (date.get(Calendar.HOUR_OF_DAY) <= end
										.get(Calendar.HOUR_OF_DAY)) {
									size++;
									if (date.get(Calendar.HOUR_OF_DAY) == end
											.get(Calendar.HOUR_OF_DAY)
											&& date.get(Calendar.MINUTE) == end
													.get(Calendar.MINUTE)
											&& end.get(Calendar.MINUTE) == 0) {
										size--;
									}
								}
							}
						}
					}
				}
			}
		}
		return size;
	}
}
